Skip to content

Conversation

stephenarosaj
Copy link
Contributor

@stephenarosaj stephenarosaj commented Sep 17, 2025

API Changes

  • Added executeQuery() and executeMutation() to src/data-connect/data-connect.ts. These allow users to call deployed operations with impersonated auth credentials.

Testing

  • New unit tests added which match the coverage of existing executeGraphql* APIs
  • New integration tests added which more than match the coverage of existing executeGraphql* APIs
  • The tests pass locally, but a re-deploy of dataconnect to the CI/CD firebase project is required. Tagging @lahirumaramba

@stephenarosaj stephenarosaj marked this pull request as ready for review September 17, 2025 22:47
@stephenarosaj
Copy link
Contributor Author

Note:

The integration tests have a huge diff because I moved the existing tests under a new parent describe(), and so their indentation level was increased. Existing tests were not changed in this PR.

@stephenarosaj
Copy link
Contributor Author

Forgot a few changes! Didn't know that you could close and re-open :P thanks Yuchen!

@stephenarosaj
Copy link
Contributor Author

wait - need to privatize the execute API, execution should come from operation refs (in a future PR)

@stephenarosaj stephenarosaj reopened this Sep 25, 2025
@stephenarosaj stephenarosaj added the release:stage Stage a release candidate label Sep 25, 2025
user_upsert(data: { id: "fred_id", address: "32 Elm St.", name: "Fred" })
}
mutation updateFredrickUserImpersonation @auth(level: USER) {
mutation updateFredrickUserImpersonation @auth(level: USER, insecureReason: "test") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: These changes likely require a re-deploy on the CI project

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, they deff do - I'll leave this comment open to make sure it gets re-deployed! Tagging @lahirumaramba

}

// @public
export function validateAdminArgs<Variables extends object>(connectorConfig: ConnectorConfig, dcOrVarsOrOptions?: DataConnect | Variables | OperationOptions, varsOrOptions?: Variables | OperationOptions, options?: OperationOptions, hasVars?: boolean, validateVars?: boolean): {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lahirumaramba Any opinions on this? We only need this for the generated SDK, and we don't intend for developers to use this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, is there a way to not export this from the public API surface?

getDataConnectStub = sinon.stub(DataConnectService.prototype, 'getDataConnect').returns(stubDcInstance);

// initializing app required, "using" it is required for successful build/compile
app = initializeApp();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might be able to get away with just calling initializeApp without setting the app to something

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was able to remove the initializeApp call entirely. Done.

});

it('should successfully parse the provided options', () => {
const { dc: dcInstance, vars: inputVars, options: inputOpts } = validateAdminArgs<object>(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason why the object is needed?

connectorConfig, variables, undefined, undefined, true, false
);
expect(dcInstance).to.deep.equal(stubDcInstance);
expect(inputVars).to.deep.equal(inputVars);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo?

Suggested change
expect(inputVars).to.deep.equal(inputVars);
expect(inputVars).to.deep.equal(variables);

// Data Connect
import './data-connect/index.spec';
import './data-connect/data-connect-api-client-internal.spec';
// import './data-connect/validate-admin-args.spec';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove comment

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should uncomment this if we want to run the tests in validate-admin-args.spec.ts

{
"name": "firebase-admin",
"version": "13.5.0",
"version": "13.4.0",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can revert this. We update the package.json only during a release PR (which we will handle separately from this PR)

public executeQuery<Data>(
name: string,
options?: OperationOptions
): Promise<ExecuteOperationResponse<Data>>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this handle the method overload correctly? If I call executeQuery('myQuery', { impersonate: ... }) would it take options as variables?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If that breaks the method overload we need to perform a runtime check to differentiate them.

public executeQuery<Data, Variables>(
  name: string,
  variablesOrOptions?: Variables | OperationOptions,
  options?: OperationOptions
): Promise<ExecuteOperationResponse<Data>> {

public executeQuery<Data>(
name: string,
options?: OperationOptions
): Promise<ExecuteOperationResponse<Data>>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If that breaks the method overload we need to perform a runtime check to differentiate them.

public executeQuery<Data, Variables>(
  name: string,
  variablesOrOptions?: Variables | OperationOptions,
  options?: OperationOptions
): Promise<ExecuteOperationResponse<Data>> {

DataConnect,
} from './data-connect'
export {
validateAdminArgs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this function is only for internal usage let's not export it to the public API surface here

* Interface representing GraphQL options.
* Interface representing ExecuteOperation response.
*/
export interface ExecuteOperationResponse<GraphqlResponse> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this interface identical to ExecuteGraphqlResponse? If that is the case and if we don't see it changing in the future, it might be better to create a type alias.

export type ExecuteOperationResponse<T> = ExecuteGraphqlResponse<T>;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release:stage Stage a release candidate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants